<template>
    <div class="drag-page-builder">
        <!-- 组件列表 -->
        <div class="component-list">
            <div v-for="group in groupedComponents" :key="group.group" class="component-group">
                <div class="group-title">{{ group.title }}</div>
                <div class="group-content">
                    <div v-for="item in group.children" :key="item.type" class="component-item" draggable="true"
                        @dragstart="handleDragStart($event, item)">
                        <el-icon class="component-icon">
                            <component :is="item.icon" />
                        </el-icon>
                        <span class="component-name">{{ item.name }}</span>
                    </div>
                </div>
            </div>
        </div>

        <!-- 画布区域 -->
        <div class="canvas-container">
            <div class="canvas" @dragover.prevent @drop="handleDrop">
                <template v-if="config.components.length">
                    <div v-for="component in config.components" :key="component.id" :class="{
                        'component-wrapper': true,
                        'is-active': currentComponent?.id === component.id
                    }" @click="handleSelectComponent(component)">
                        <div class="component-actions">
                            <el-button type="danger" link class="delete-btn"
                                @click.stop="handleDeleteComponent(component.id)">
                                <el-icon>
                                    <Delete />
                                </el-icon>
                            </el-button>
                        </div>
                        <component :is="resolveComponent(component.type)" v-bind="component.props.base"
                            :style="component.props.style" :model-value="config.formData[component.id]"
                            :validation="config.validation[component.id]"
                            @update:model-value="handleFormValueUpdate(component.id, $event)"
                            @validate="handleValidate(component.id, $event)" />
                    </div>
                </template>
                <div v-else class="empty-tip">
                    <el-icon>
                        <Plus />
                    </el-icon>
                    <span>从左侧拖入组件开始构建</span>
                </div>
            </div>
        </div>

        <!-- 属性面板 -->
        <div v-if="currentComponent" class="property-panel">
            <el-tabs v-model="activeName">
                <el-tab-pane label="基础属性" name="base">
                    <component :is="getPropertyPanel(currentComponent.type)" v-model:props="currentComponent.props.base"
                        @update:props="handlePropsUpdate" />
                </el-tab-pane>
                <el-tab-pane label="样式属性" name="style">
                    <style-panel v-model:props="currentComponent.props.style" @update:props="handlePropsUpdate" />
                </el-tab-pane>
            </el-tabs>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, markRaw, onMounted, h, defineComponent, watch } from 'vue'
import { Edit, Delete, Document, Plus, Select as SelectIcon, Switch as SwitchIcon, DCaret } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import type { ComponentGroup, ComponentDefinition, ComponentInstance, PageConfig } from '@/types/component'
import { ComponentType, ComponentGroupEnum, ComponentGroupTitles } from '@/types/component'
import { registerComponent, getComponentByType, getComponentConfig } from '@/utils/componentRegistry'
import { pluginManager } from '@/utils/plugins'
import FormInput from './components/form/input/index.vue'
import StylePanel from '@/components/PropertyPanels/StylePanel.vue'

interface ComponentEmits {
    (e: 'update:modelValue', value: unknown): void;
    (e: 'validate', valid: boolean): void;
}

// 组件列表
const componentList = ref<ComponentDefinition[]>([
    // 本地组件
    {
        type: ComponentType.INPUT,
        name: '输入框',
        group: ComponentGroupEnum.FORM,
        icon: markRaw(Edit),
        component: markRaw(FormInput),
        props: {
            base: {
                modelValue: '',
                label: '输入框',
                placeholder: '请输入'
            },
            style: {}
        }
    },
    {
        type: ComponentType.SELECT,
        name: '选择框',
        group: ComponentGroupEnum.FORM,
        icon: markRaw(SelectIcon),
        component: markRaw(defineComponent({
            name: 'FormSelect',
            template: `
                <el-form-item :label="label">
                    <el-select
                        :model-value="modelValue"
                        :placeholder="placeholder"
                        @update:modelValue="$emit('update:modelValue', $event)"
                    >
                        <el-option
                            v-for="item in options"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>
            `,
            props: {
                modelValue: [String, Number],
                label: String,
                placeholder: String,
                options: {
                    type: Array,
                    default: () => []
                }
            },
            emits: ['update:modelValue']
        })),
        props: {
            base: {
                modelValue: '',
                label: '选择框',
                placeholder: '请选择',
                options: [
                    { label: '选项1', value: '1' },
                    { label: '选项2', value: '2' }
                ]
            },
            style: {}
        }
    },
    {
        type: ComponentType.SWITCH,
        name: '开关',
        group: ComponentGroupEnum.FORM,
        icon: markRaw(SwitchIcon),
        component: markRaw(defineComponent({
            name: 'FormSwitch',
            template: `
                <el-form-item :label="label">
                    <el-switch
                        :model-value="modelValue"
                        @update:modelValue="$emit('update:modelValue', $event)"
                    />
                </el-form-item>
            `,
            props: {
                modelValue: Boolean,
                label: String
            },
            emits: ['update:modelValue']
        })),
        props: {
            base: {
                modelValue: false,
                label: '开关'
            },
            style: {}
        }
    },
    {
        type: ComponentType.COUNTER,
        name: '计数器',
        group: ComponentGroupEnum.FORM,
        icon: markRaw(Plus),
        component: markRaw(defineComponent({
            name: 'FormCounter',
            template: `
                <el-form-item :label="label">
                    <el-input-number
                        :model-value="modelValue"
                        :min="min"
                        :max="max"
                        @update:modelValue="$emit('update:modelValue', $event)"
                    />
                </el-form-item>
            `,
            props: {
                modelValue: Number,
                label: String,
                min: {
                    type: Number,
                    default: 1
                },
                max: {
                    type: Number,
                    default: 100
                }
            },
            emits: ['update:modelValue']
        })),
        props: {
            base: {
                modelValue: 0,
                label: '计数器',
                min: 1,
                max: 100
            },
            style: {}
        }
    },
    {
        type: ComponentType.DIVIDER,
        name: '分割线',
        group: ComponentGroupEnum.AUXILIARY,
        icon: markRaw(DCaret),
        component: markRaw(defineComponent({
            name: 'FormDivider',
            template: '<el-divider :style="style" />',
            props: {
                style: {
                    type: Object,
                    default: () => ({})
                }
            }
        })),
        props: {
            base: {},
            style: {}
        }
    },
    {
        type: ComponentType.TEXT,
        name: '文字',
        group: ComponentGroupEnum.AUXILIARY,
        icon: markRaw(Document),
        component: markRaw(defineComponent({
            name: 'FormText',
            template: '<div :style="style">{{ content }}</div>',
            props: {
                content: String,
                style: {
                    type: Object,
                    default: () => ({})
                }
            }
        })),
        props: {
            base: {
                content: '文本内容'
            },
            style: {}
        }
    }
])

// 分组后的组件列表
const groupedComponents = computed<ComponentGroup[]>(() => {
    const groups: Record<ComponentGroupEnum, ComponentGroup> = {
        [ComponentGroupEnum.FORM]: {
            group: ComponentGroupEnum.FORM,
            title: ComponentGroupTitles[ComponentGroupEnum.FORM],
            children: []
        },
        [ComponentGroupEnum.LAYOUT]: {
            group: ComponentGroupEnum.LAYOUT,
            title: ComponentGroupTitles[ComponentGroupEnum.LAYOUT],
            children: []
        },
        [ComponentGroupEnum.AUXILIARY]: {
            group: ComponentGroupEnum.AUXILIARY,
            title: ComponentGroupTitles[ComponentGroupEnum.AUXILIARY],
            children: []
        }
    }

    // 分配本地组件
    componentList.value.forEach((component: ComponentDefinition) => {
        if (component.group && groups[component.group]) {
            // 检查是否已经存在相同类型的组件
            const exists = groups[component.group].children.some(
                child => child.type === component.type
            )
            if (!exists) {
                groups[component.group].children.push(component)
            }
        }
    })

    // 分配远程组件
    const remoteComponents = pluginManager.getAllComponents()
    remoteComponents.forEach((component: ComponentDefinition) => {
        if (component.group && groups[component.group as ComponentGroupEnum]) {
            // 检查是否已经存在相同类型的组件
            const exists = groups[component.group as ComponentGroupEnum].children.some(
                child => child.type === component.type
            )
            if (!exists) {
                groups[component.group as ComponentGroupEnum].children.push(component)
            }
        }
    })

    return Object.values(groups).filter(group => group.children.length > 0)
})

// 预览状态
const showPreview = ref(false)

// 页面配置
const config = ref<PageConfig>({
    components: [],
    formData: {},
    validation: {},
    layout: {
        type: 'flex',
        gutter: 20,
        responsive: true
    },
    settings: {
        theme: 'light',
        responsive: true,
        spacing: {
            padding: '20px',
            margin: '10px'
        }
    }
})

// 当前选中的组件
const currentComponent = ref<ComponentInstance | null>(null)

// 激活的标签页
const activeName = ref('base')

// 预览JSON
const previewJson = computed(() => {
    return {
        components: config.value.components.map(comp => ({
            id: comp.id,
            type: comp.type,
            category: comp.category,
            props: comp.props
        })),
        formData: config.value.formData,
        validation: config.value.validation,
        layout: config.value.layout,
        settings: config.value.settings
    }
})

// 解析组件
const resolveComponent = (type: ComponentType) => {
    // 先从注册的组件中查找
    const registeredComponent = getComponentByType(type)
    if (registeredComponent?.component) {
        return markRaw(registeredComponent.component)
    }

    // 如果没有找到，从插件组件中查找
    const pluginComponents = pluginManager.getAllComponents()
    const pluginComponent = pluginComponents.find((comp: ComponentDefinition) => comp.type === type)

    if (pluginComponent?.template) {
        // 创建虚拟组件
        return markRaw(defineComponent({
            name: `virtual-${type}`,
            template: pluginComponent.template,
            props: {
                modelValue: [String, Number, Boolean, Object, Array],
                label: String,
                placeholder: String,
                validation: Boolean,
                required: Boolean,
                ...pluginComponent.props.base
            },
            emits: ['update:modelValue', 'validate'],
            setup(props, { emit }) {
                // 监听modelValue的变化
                watch(() => props.modelValue, (newVal) => {
                    if (props.required) {
                        emit('validate', !!newVal)
                    } else {
                        emit('validate', true)
                    }
                }, { immediate: true })

                return {
                    updateValue: (value: unknown) => {
                        emit('update:modelValue', value)
                    }
                }
            }
        }))
    }

    return null
}

// 获取属性面板组件
const getPropertyPanel = (type: ComponentType) => {
    // 先从注册的组件中查找
    const registeredComponent = getComponentByType(type)
    if (registeredComponent?.propertyPanel) {
        return registeredComponent.propertyPanel
    }

    // 如果没有找到，从插件组件中查找
    const pluginComponents = pluginManager.getAllComponents()
    const pluginComponent = pluginComponents.find(comp => comp.type === type)
    if (pluginComponent?.propertyPanel) {
        return pluginComponent.propertyPanel
    }

    // 如果都没有找到，返回默认的基础属性面板
    return defineComponent({
        name: 'DefaultPropertyPanel',
        template: `
            <div class="property-form">
                <el-form label-width="80px">
                    <el-form-item label="标签">
                        <el-input v-model="props.label" />
                    </el-form-item>
                    <el-form-item label="占位符" v-if="hasPlaceholder">
                        <el-input v-model="props.placeholder" />
                    </el-form-item>
                    <el-form-item label="必填" v-if="hasRequired">
                        <el-switch v-model="props.required" />
                    </el-form-item>
                    <el-form-item label="内容" v-if="hasContent">
                        <el-input type="textarea" v-model="props.content" :rows="3" />
                    </el-form-item>
                    <el-form-item label="选项" v-if="hasOptions">
                        <div v-for="(option, index) in props.options" :key="index" class="option-item">
                            <el-input v-model="option.label" placeholder="选项名" class="option-input" />
                            <el-input v-model="option.value" placeholder="选项值" class="option-input" />
                            <el-button type="danger" link @click="removeOption(index)">删除</el-button>
                        </div>
                        <el-button type="primary" link @click="addOption">添加选项</el-button>
                    </el-form-item>
                    <el-form-item label="最小值" v-if="hasRange">
                        <el-input-number v-model="props.min" />
                    </el-form-item>
                    <el-form-item label="最大值" v-if="hasRange">
                        <el-input-number v-model="props.max" />
                    </el-form-item>
                </el-form>
            </div>
        `,
        props: {
            props: {
                type: Object,
                required: true
            }
        },
        emits: ['update:props'],
        setup(props, { emit }) {
            const hasPlaceholder = computed(() =>
                'placeholder' in props.props
            )

            const hasRequired = computed(() =>
                'required' in props.props
            )

            const hasContent = computed(() =>
                'content' in props.props
            )

            const hasOptions = computed(() =>
                'options' in props.props
            )

            const hasRange = computed(() =>
                'min' in props.props && 'max' in props.props
            )

            const addOption = () => {
                if (props.props.options) {
                    props.props.options.push({ label: '', value: '' })
                    emit('update:props', { ...props.props })
                }
            }

            const removeOption = (index: number) => {
                if (props.props.options) {
                    props.props.options.splice(index, 1)
                    emit('update:props', { ...props.props })
                }
            }

            return {
                hasPlaceholder,
                hasRequired,
                hasContent,
                hasOptions,
                hasRange,
                addOption,
                removeOption
            }
        }
    })
}

// 处理组件选中
const handleSelectComponent = (component: ComponentInstance) => {
    currentComponent.value = component
    activeName.value = 'base'
}

// 处理属性更新
const handlePropsUpdate = () => {
    // 强制重新渲染
    config.value = { ...config.value }
}

// 处理验证
const handleValidate = (id: string, isValid: boolean) => {
    config.value.validation[id] = isValid
}

// 处理拖拽开始
const handleDragStart = (event: DragEvent, item: ComponentDefinition) => {
    event.dataTransfer?.setData('componentType', JSON.stringify(item))
}

// 处理拖拽放置
const handleDrop = (event: DragEvent) => {
    event.preventDefault()
    const componentData = event.dataTransfer?.getData('componentType')
    if (!componentData) return

    try {
        const item = JSON.parse(componentData) as ComponentDefinition
        console.log('Dropped component:', item)

        // 获取组件配置
        let componentConfig: ComponentDefinition | undefined

        // 先从注册的组件中查找
        componentConfig = getComponentConfig(item.type)

        // 如果没有找到，从插件组件中查找
        if (!componentConfig) {
            const pluginComponents = pluginManager.getAllComponents()
            componentConfig = pluginComponents.find(comp => comp.type === item.type)
        }

        if (!componentConfig) {
            throw new Error(`Component type ${item.type} not found`)
        }

        const newComponent: ComponentInstance = {
            id: `${item.type}_${Date.now()}`,
            type: item.type,
            category: item.category,
            props: {
                base: { ...componentConfig.props.base },
                style: { ...componentConfig.props.style }
            },
            sort: config.value.components.length
        }

        console.log('Created new component:', newComponent)

        // 设置默认值和验证状态
        config.value.components.push(newComponent)
        config.value.formData[newComponent.id] = componentConfig.props.base.modelValue ?? null
        config.value.validation[newComponent.id] = true

        // 自动选中新添加的组件
        currentComponent.value = newComponent
        activeName.value = 'base'

        // 提示成功
        ElMessage.success('添加组件成功')
    } catch (err) {
        console.error('Failed to parse component data:', err)
        ElMessage.error('添加组件失败')
    }
}

// 处理表单值更新
const handleFormValueUpdate = (id: string, value: unknown) => {
    config.value.formData[id] = value
}

// 处理表单验证
const handleFormValidate = (id: string, valid: boolean) => {
    config.value.validation[id] = valid
}

// 处理删除组件
const handleDeleteComponent = (id: string) => {
    const index = config.value.components.findIndex(item => item.id === id)
    if (index !== -1) {
        config.value.components.splice(index, 1)
        delete config.value.formData[id]
        delete config.value.validation[id]
        if (currentComponent.value?.id === id) {
            currentComponent.value = null
        }
    }
}

// 表单是否有效
const isFormValid = computed(() => {
    return Object.values(config.value.validation).every(Boolean)
})

// 处理保存
const handleSave = () => {
    showPreview.value = true
}

// 复制JSON
const handleCopyJson = async () => {
    try {
        await navigator.clipboard.writeText(JSON.stringify(previewJson.value, null, 2))
        ElMessage.success('复制成功')
    } catch (err) {
        ElMessage.error('复制失败')
    }
}

// 初始化组件
const initializeComponents = () => {
    try {
        // 注册本地组件
        componentList.value.forEach(component => {
            registerComponent(component)
        })

        // 注册远程组件示例
        const remoteInput = {
            type: ComponentType.REMOTE_INPUT,
            name: '远程输入框',
            group: ComponentGroupEnum.FORM,
            icon: markRaw(Edit),
            template: `
                <div class="remote-input">
                    <el-form-item :label="label">
                        <el-input
                            v-model="modelValue"
                            :placeholder="placeholder"
                            @update:modelValue="$emit('update:modelValue', $event)"
                        />
                    </el-form-item>
                </div>
            `,
            props: {
                base: {
                    modelValue: '',
                    label: '远程输入框',
                    placeholder: '请输入'
                },
                style: {}
            }
        }

        pluginManager.registerComponent(remoteInput)

        ElMessage.success('组件加载成功')
    } catch (error) {
        console.error('Failed to initialize components:', error)
        ElMessage.error('加载组件失败')
    }
}

onMounted(() => {
    initializeComponents()
})
</script>

<style lang="scss" scoped>
.drag-page-builder {
    display: flex;
    height: 100%;
    background-color: var(--bg-color);

    .component-list {
        width: 260px;
        padding: 16px;
        background-color: var(--bg-color);
        border-right: 1px solid var(--border-color);
        overflow-y: auto;

        .component-group {
            margin-bottom: 16px;

            .group-title {
                font-size: 14px;
                color: #606266;
                margin-bottom: 8px;
            }

            .group-content {
                display: grid;
                grid-template-columns: repeat(2, 1fr);
                gap: 8px;
            }

            .component-item {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                height: 80px;
                background-color: var(--bg-color);
                border: 1px solid var(--border-color);
                border-radius: 4px;
                cursor: move;
                transition: all 0.3s;

                &:hover {
                    background-color: var(--bg-color);
                    border-color: #409eff;
                }

                .component-icon {
                    font-size: 24px;
                    color: #606266;
                    margin-bottom: 8px;
                }

                .component-name {
                    font-size: 12px;
                    color: #606266;
                }
            }
        }
    }

    .canvas-container {
        flex: 1;
        padding: 16px;
        overflow-y: auto;

        .canvas {
            min-height: 100%;
            background-color: var(--bg-color);
            border: 1px solid var(--border-color);
            border-radius: 4px;
            padding: 16px;

            .component-wrapper {
                position: relative;
                margin-bottom: 16px;
                border: 1px dashed transparent;
                padding: 8px;
                transition: all 0.3s;

                &:hover {
                    border-color: var(--el-border-color);

                    .component-actions {
                        display: flex;
                    }
                }

                &.is-active {
                    border-color: var(--el-border-color);

                    background-color: var(--bg-color);

                    .component-actions {
                        display: flex;
                    }
                }

                .component-actions {
                    display: none;
                    position: absolute;
                    top: 4px;
                    right: 4px;
                    // z-index: 10;
                    background-color: var(--bg-color);
                    border-radius: 4px;
                    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
                    padding: 4px;

                    .delete-btn {
                        padding: 4px;
                        font-size: 16px;

                        &:hover {
                            color: #f56c6c;
                            background-color: #fef0f0;
                        }
                    }
                }
            }

            .empty-tip {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                height: 200px;
                color: #909399;
                font-size: 14px;

                .el-icon {
                    font-size: 32px;
                    margin-bottom: 8px;
                }
            }
        }
    }

    .property-panel {
        width: 300px;
        background-color: var(--bg-color);
        border-left: 1px solid var(--border-color);
        padding: 16px;
        overflow-y: auto;

        :deep(.el-tabs__header) {
            margin-bottom: 16px;
        }
    }
}

.property-form {
    .option-item {
        display: flex;
        gap: 8px;
        margin-bottom: 8px;
        align-items: center;

        .option-input {
            flex: 1;
        }
    }
}
</style>